/* Copyright */
/*******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Tsunagi-BPM
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *******************************************************************************/
 /* Copyright End */
 
package tsunagi.rest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import tsunagi.json.path.JsonPath;

/**
 * JsonData consists of followings (example):
 * 
 * {
 *  "retVal":"xxx", = "1" means true "0" means false "2" means warning
 *  "errorNo": "1-1000:system defined, 10000-above: user defined",
 *  "errorInfo":"error message",
 *  "params": {
 *    "param1":"1111",
 *    "param2":"2222"
 *  },
 *  "arrayParam":[
 *        {
 *    	   "param1":"aaaa",
 *   	   "param2":"bbbb"
 *   	  },
 *   	  {
 *   	   "param1":"cccc",
 *   	   "param2":"dddd"
 *   	  }
 *   ]
 *}
 *
 */
public class JsonData extends JSONObject {
	public static final String RETVAL = "retVal";
	/**
	 * Success return value 
	 */
	public static final String RETVAL_FAILED = "0";
	public static final String RETVAL_SUCCESS = "1";
	public static final String RETVAL_WARNING = "2";

	public static final String ERROR_NO = "errorNo";
	public static final String ERROR_INFO = "errorInfo";
	public static final String PARAMS = "params";
	public static final String ARRAY_PARAM = "arrayParam";
	
	private JsonPath jsonPath;
	
	public JsonData() {
		super();
	}
	
	public JsonData(String data) {
		super(data);
	}
	
	public JsonData setRetVal(String val) {
		this.put(RETVAL, val);
		return this;
	}
	
	public JsonData setSuccess() {
		this.setRetVal(RETVAL_SUCCESS);
		return this;
	}
	
	public JsonData setWarning(String message) {
		this.setRetVal(RETVAL_WARNING);
		this.setErrorInfo(message);
		return this;
	}
	
	public JsonData setError(String errorNo, String message) {
		this.setRetVal(RETVAL_FAILED);
		this.setErrorNo(errorNo);
		this.setErrorInfo(message);
		return this;
	}

	public String getRetVal() {
		return this.getString(RETVAL);
	}
	
	public JsonData setErrorInfo(String val) {
		this.put(ERROR_INFO, val);
		return this;
	}
	
	public String getErrorInfo() {
		return this.getString(ERROR_INFO);
	}
	
	public JsonData setErrorNo(String val) {
		this.put(ERROR_NO, val);
		return this;
	}
	
	public String getErrorNo() {
		return this.getString(ERROR_NO);
	}

	protected JsonData setJsonPath(JsonPath path) {
		jsonPath = path;
		return this;
	}

	protected JsonPath getJsonPath() {
		return jsonPath;
	}
	
	/**
	 * 
	 * @param key
	 * @param obj This type must be String or JSONObject.
	 */
	public JsonData addParams(String key, Object obj) {
		try {
			get(PARAMS);
		} catch(JSONException e) {
			this.put(PARAMS, new JSONObject());
		}
		this.getJSONObject(PARAMS).put(key, obj);
		return this;
	}
	
	public Object getParams(String key) {
		Object result = null;
		try {
			result = this.getJSONObject(PARAMS).getString(key);
		} catch(JSONException e) {
			// do nothing
		}
		return result;
	}
	
	public JsonData addArrayParam(JSONObject obj) {
		try {
			get(ARRAY_PARAM);
		} catch(JSONException e) {
			this.put(ARRAY_PARAM, new JSONArray());
		}
		this.getJSONArray(ARRAY_PARAM).put(obj);
		return this;
	}
	
	public JsonData addArrayParam(JSONArray array) {
		try {
			get(ARRAY_PARAM);
		} catch(JSONException e) {
			this.put(ARRAY_PARAM, array);
		}
		return this;
	}

	public JSONObject getArrayParam(int index) {
		JSONObject result = null;
		try {
			result = (JSONObject)this.getJSONArray(ARRAY_PARAM).get(index);
		} catch(JSONException e) {
			// do nothing
		}
		return result;
	}
	
	public void initPath() {
		this.setJsonPath(new JsonPath(this.toString()));
	}
	
	public Object getFromPath(String path) {
		return this.getJsonPath().get(path);
	}
	
	public static final void main(String[] args) {
		JsonData jd = new JsonData();
		jd.setRetVal(RETVAL_SUCCESS);
		jd.setError("111", "This is first error.");
		jd.addParams("prop1", "AAA");
		jd.addParams("prop2", new JSONObject());
		jd.addParams("prop3", 1.5);
		jd.addArrayParam(new JSONObject());
		jd.addArrayParam(new JSONObject());
		System.out.println(jd);
		
		JsonData jd2 = new JsonData(jd.toString());
		System.out.println(jd2.getRetVal());
		System.out.println(jd2.getErrorInfo());
	}
}
